package com.travel.server.manager.impl.command.upload;

import com.travel.common.CommonConstant;
import com.travel.common.exception.WorkCode;
import com.travel.common.exception.WorkException;
import com.travel.common.util.CollectionUtil;
import com.travel.common.util.CommonUtil;
import com.travel.common.util.DateUtil;
import com.travel.server.manager.impl.command.BaseImportCommand;
import com.travel.server.manager.impl.dal.CustomerDal;
import com.travel.server.manager.impl.dal.MemberGradeDal;
import com.travel.server.manager.impl.dal.MemberGradeDal.MemberGradeParam;
import com.travel.server.manager.impl.dal.OrderDal;
import com.travel.server.manager.impl.dal.UserDal;
import com.travel.server.manager.impl.dal.UserDal.UserParam;
import com.travel.server.manager.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: LiZhenhui
 * @Date: 2018/11/22 15:11
 * @Desc:
 */
@Component
@Slf4j
public class UploadFileCommand extends BaseImportCommand {

    @Autowired
    private OrderDal orderDal;

    @Autowired
    private CustomerDal customerDal;

    @Autowired
    private MemberGradeDal memberGradeDal;

    @Autowired
    private UserDal userDal;

    private final static String CUSTOMER_NOT_EXIST_PRE = "导入失败，以下用户信息不存在：";

    private final static String CUSTOMER_EXIST_PRE = "导入失败，以下用户姓名-手机号已存在：";

    private final static String CUSTOMER_REPEAT_PRE = "导入失败，Excel表格中存在相同的客户姓名和手机号：";

    private final static String ORDER_ID_EXIST_PRE = "导入失败，以下订单号已存在：";

    private final static String ORDER_ID_REPEAT_PRE = "导入失败，Excel表格中存在相同的订单号：";

    public void importOrder(InputStream fileInputStream, UserInfo userInfo){
        try {
            Date now = new Date();
            Map<String, CustomerInfo> customerMap = new HashMap<>();
            Map<String, ProjectSpecial> projectMap = new HashMap<>();
            Map<String, UserInfo> userInfoMap = new HashMap<>();
            Set<String> notExistProject = new HashSet<>();
            Set<String> notExistCustomer = new HashSet<>();
            Set<String> existOrderId = new HashSet<>();
            Set<String> repeatOrderId = new HashSet<>();
            Set<String> notExistCharge = new HashSet<>();
            List<OrderInfo> list = new ArrayList<>();
            XSSFWorkbook  wb = new XSSFWorkbook(fileInputStream);
            XSSFSheet sheet = wb.getSheetAt(0);
            for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
                XSSFRow row = sheet.getRow(rowNum);
                XSSFCell cell0 = row.getCell(0);
                if(cell0 == null || cell0.getCellType() == XSSFCell.CELL_TYPE_BLANK){
                    break;
                }
                String orderId = getValue(cell0);
                String projectName = getValue(row.getCell(1));
                String teamNumber = getValue(row.getCell(2));
                String orderType = getValue(row.getCell(3));
                String travelDateStr = getValue(row.getCell(4));
                String discount = getValue(row.getCell(5));
                String total = getValue(row.getCell(6));
                String applyAmount = getValue(row.getCell(7));
                String customerName = getValue(row.getCell(8));
                String note = getValue(row.getCell(9));
                String rechargeName = getValue(row.getCell(10));
                if(StringUtils.isBlank(orderId) || StringUtils.isBlank(projectName) || StringUtils.isBlank(teamNumber) || StringUtils.isBlank(orderType)
                        || StringUtils.isBlank(travelDateStr) || StringUtils.isBlank(total) || StringUtils.isBlank(customerName)){
                    throw new WorkException(WorkCode.ORDER_EXCEL_DATA_EMPTY);
                }
                log.info("导入订单数据，第" + rowNum + "行>>" + orderId + "|" + projectName + "|" + teamNumber + "|" + orderType + "|" + travelDateStr
                        + "|" + discount + "|" + total + "|" + customerName + "|" + note + "|" + rechargeName);

                OrderInfo oldOrder = orderDal.selectByOrderId(orderId);
                if(oldOrder != null){
                    existOrderId.add(orderId);
                }
                if(!repeatOrderId.add(orderId)){
                    WorkCode workCode = WorkCode.ORDER_ID_REPEAT;
                    workCode.setMessage(ORDER_ID_REPEAT_PRE + orderId);
                    log.info("excel存在相同的记录 {}", orderId);
                    throw new WorkException(workCode);
                }
                Date travelDate;
                try{
                    travelDate = DateUtil.YYYY_MM_DD.parse(travelDateStr);
                }catch (Exception e){
                    throw new WorkException(WorkCode.EXCEL_DATE_NOT_CORRECT);
                }
                String specialMsg = projectName + CommonConstant.DASH_STR + travelDateStr;
                ProjectSpecial special = projectMap.get(specialMsg);
                if(special == null) {
                    special = querySpecial(projectName, travelDate);
                }
                if(special == null){
                    log.info("未查询到项目名称 {} 和出行日期 {} 对应的项目规格", projectName, travelDateStr);
                    notExistProject.add(specialMsg);
                    continue;
                }
                projectMap.put(specialMsg, special);
                CustomerInfo customerInfo = customerMap.get(customerName);
                if(customerInfo == null) {
                    customerInfo = queryCustomer(customerName, null);
                }
                if(customerInfo == null){
                    log.info("未查询到客户姓名 {} 对应的客户信息", customerName);
                    notExistCustomer.add(customerName);
                    continue;
                }
                customerMap.put(customerName, customerInfo);
                UserParam param = new UserParam();
                param.setRealName(rechargeName);
                UserInfo recharge = userInfoMap.get(rechargeName);
                if(recharge == null){
                    recharge = CollectionUtil.getFirst(userDal.selectByExample(param));
                }
                if(recharge == null){
                    log.info("未查询到订单负责人姓名 {} 对应的用户信息", rechargeName);
                    notExistCharge.add(rechargeName);
                    continue;
                }
                userInfoMap.put(rechargeName, recharge);

                OrderInfo orderInfo = new OrderInfo();
                orderInfo.setSpecialId(special.getId());
                orderInfo.setOrderId(orderId);
                orderInfo.setTeamNumber(teamNumber);
                orderInfo.setOrderType(orderType);
                if(StringUtils.isNotBlank(discount)) {
                    orderInfo.setDiscountAmount(CommonUtil.yuanToFen(new BigDecimal(discount)).intValue());
                }
                if(StringUtils.isNotBlank(applyAmount)){
                    orderInfo.setApplyAmount(CommonUtil.yuanToFen(new BigDecimal(applyAmount)).intValue());
                }
                orderInfo.setOrderTotal(1);
                if(StringUtils.isNotBlank(total)) {
                    orderInfo.setOrderAmount(CommonUtil.yuanToFen(new BigDecimal(total)).longValue());
                }
                orderInfo.setNote(note);
                orderInfo.setCustomerId(customerInfo.getId());
                orderInfo.setCreateTime(now);
                orderInfo.setCreateBy(userInfo.getName());
                orderInfo.setUpdateTime(now);
                orderInfo.setUpdateBy(userInfo.getName());
                orderInfo.setTravelStartTime(travelDate);
                orderInfo.setOrderChargeId(recharge.getId());
                orderInfo.setOrderChargeName(recharge.getName());
                //订单标记，3导入
                orderInfo.setOrderMark(3);
                Integer day = CommonUtil.getDays(special.getDays());
                if(day != null){
                    Date endDate = DateUtil.getDateNum(special.getTravelDate(), day);
                    orderInfo.setTravelEndTime(endDate);
                }
                list.add(orderInfo);
            }
            if(!CollectionUtil.isEmpty(existOrderId)){
                String message = CommonConstant.EMPTY_STR;
                for(String msg : existOrderId){
                    message = message + msg + CommonConstant.SEMICOLON_STR;
                }
                message = message.substring(0, message.length() - 1);
                WorkCode workCode = WorkCode.CUSTOMER_EXIST;
                workCode.setMessage(ORDER_ID_EXIST_PRE + message);
                throw new WorkException(workCode);
            }
            if(!CollectionUtil.isEmpty(notExistProject)){
                String message = CommonConstant.EMPTY_STR;
                for(String msg : notExistProject){
                    message = message + msg + CommonConstant.SEMICOLON_STR;
                }
                message = message.substring(0, message.length() - 1);
                WorkCode workCode = WorkCode.PROJECT_SPECIAL_NOT_EXIST;
                workCode.setMessage(PROJECT_NOT_EXIST_PRE + message);
                throw new WorkException(workCode);
            }else if(!CollectionUtil.isEmpty(notExistCustomer)){
                String message = CommonConstant.EMPTY_STR;
                for(String msg : notExistCustomer){
                    message = message + msg + CommonConstant.SEMICOLON_STR;
                }
                message = message.substring(0, message.length() - 1);
                WorkCode workCode = WorkCode.CUSTOMER_NOT_EXIST;
                workCode.setMessage(CUSTOMER_NOT_EXIST_PRE + message);
                throw new WorkException(workCode);
            }
            if(CollectionUtil.isEmpty(list)) {
                throw new WorkException(WorkCode.EXCEL_EMPTY);
            }
            orderDal.batchInsert(list);
        }catch (WorkException e){
            throw e;
        }catch (Exception e){
            log.error("导入订单Excel异常：", e);
            throw new WorkException(WorkCode.SYSTEM);
        }
    }

    public void importCustomer(InputStream fileInputStream, UserInfo userInfo, Integer isMember){
        try{
            Integer memberGradeId = null;
            if(CommonConstant.YES.equals(isMember)){
                MemberGradeInfo memberGradeInfo = queryMember();
                if(memberGradeInfo != null){
                    memberGradeId = memberGradeInfo.getId();
                }
            }
            Date now = new Date();
            Set<String> repeatCustomer = new HashSet<>();
            Set<String> existCustomer = new HashSet<>();
            List<CustomerInfo> list = new ArrayList<>();
            XSSFWorkbook  wb = new XSSFWorkbook(fileInputStream);
            XSSFSheet sheet = wb.getSheetAt(0);
            for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
                XSSFRow row = sheet.getRow(rowNum);
                XSSFCell cell0 = row.getCell(0);
                if(cell0 == null || cell0.getCellType() == XSSFCell.CELL_TYPE_BLANK){
                    break;
                }
                String customerName = getValue(cell0);
                String mobile = getValue(row.getCell(1));
                String sex = getValue(row.getCell(2));
                String birthDateStr = getValue(row.getCell(3));
                String wechatNumber = getValue(row.getCell(4));
                String mail = getValue(row.getCell(5));
                log.info("导入客户数据，第" + rowNum + "行>>" + customerName + "|" + mobile + "|" + sex + "|" + birthDateStr + "|" + wechatNumber + "|" + mail);
                Date birthDate;
                try{
                    birthDate = DateUtil.YYYY_MM_DD.parse(birthDateStr);
                }catch (Exception e){
                    throw new WorkException(WorkCode.EXCEL_DATE_NOT_CORRECT);
                }
                if(StringUtils.isBlank(customerName) || StringUtils.isBlank(mobile)){
                    throw new WorkException(WorkCode.CUSTOMER_EXCEL_DATA_EMPTY);
                }
                CustomerInfo customerInfo = queryCustomer(customerName, mobile);
                String msg = customerName + CommonConstant.DASH_STR + mobile;
                if(customerInfo != null){
                    log.info("姓名 {} 手机号 {} 已存在客户表中", customerName, mobile);
                    existCustomer.add(msg);
                }
                if(!repeatCustomer.add(msg)){
                    WorkCode workCode = WorkCode.CUSTOMER_REPEAT;
                    workCode.setMessage(CUSTOMER_REPEAT_PRE + msg);
                    log.info("excel存在相同的记录 {}", msg);
                    throw new WorkException(workCode);
                }
                customerInfo = new CustomerInfo();
                customerInfo.setName(customerName);
                customerInfo.setMobile(mobile);
                customerInfo.setSex(sex);
                customerInfo.setBirthDate(birthDate);
                customerInfo.setWechatNumber(wechatNumber);
                customerInfo.setCreateBy(userInfo.getName());
                customerInfo.setCreateTime(now);
                customerInfo.setBeCustomerTime(now);
                customerInfo.setUpdateBy(userInfo.getName());
                customerInfo.setUpdateTime(now);
                customerInfo.setState(CommonConstant.YES);
                customerInfo.setSource("外部导入");
                customerInfo.setIsMember(isMember);
                customerInfo.setMemberGradeId(memberGradeId);
                customerInfo.setMail(mail);
                list.add(customerInfo);
            }
            if(!CollectionUtil.isEmpty(existCustomer)){
                String message = CommonConstant.EMPTY_STR;
                for(String msg : existCustomer){
                    message = message + msg + CommonConstant.SEMICOLON_STR;
                }
                message = message.substring(0, message.length() - 1);
                WorkCode workCode = WorkCode.CUSTOMER_EXIST;
                workCode.setMessage(CUSTOMER_EXIST_PRE + message);
                throw new WorkException(workCode);
            }
            if(CollectionUtil.isEmpty(list)) {
                throw new WorkException(WorkCode.EXCEL_EMPTY);
            }
            customerDal.batchInsert(list);
        }catch (WorkException e){
            throw e;
        }catch (Exception e){
            log.error("导入客户excel异常：", e);
            throw new WorkException(WorkCode.SYSTEM);
        }
    }

    /**
     * 查询会员对应的等级id
     * @return
     */
    private MemberGradeInfo queryMember(){
        MemberGradeParam param = new MemberGradeParam();
        param.setName("会员");
        List<MemberGradeInfo> list = memberGradeDal.selectByExample(param);
        return CollectionUtil.getFirst(list);
    }

    private static Integer getFreightAmount(OrderInfo orderInfo, String total){
        Integer totalAmount = CommonUtil.yuanToFen(new BigDecimal(total)).intValue();

        long freightAmount = totalAmount - (orderInfo.getOrderAmount() == null?0:orderInfo.getOrderAmount()) + (orderInfo.getDiscountAmount() == null?0:orderInfo.getDiscountAmount());
        return Integer.parseInt(String.valueOf(freightAmount));
    }

}
